package ru.vsu.amm.io;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Array;
import java.nio.charset.Charset;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.List;

/**
 * 
 * @author Иванов Илья
 * @since 20 января 2013
 *
 */
public class FuzzyIO {
	
	@SuppressWarnings("unchecked")
	public static <T> List<T[]> readScores(String fileName, Class<T> scoreClass) {
		if (fileName == null)
			return null;
		
		try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
			List<T[]> vectors = new ArrayList<>();
			
			String line;
			while ((line = reader.readLine()) != null) {
				line = line.trim();
				String[] values = line.split("\\s+");
				List<T> vector = new ArrayList<>();
				
				for (String value : values) {
					if (value.isEmpty())
						continue;
					
					vector.add((T) scoreClass.getMethod("valueOf", String.class).invoke(null, value));
				}
				
				if (!vector.isEmpty())
					vectors.add(vector.toArray((T[]) Array.newInstance(scoreClass, vector.size())));
			}
			
			return vectors;
		} catch (Exception e) {
			return null;
		}
	}
	
	public static <T, V> void writeAggregationResults(T[] weights, V[][] results, Class<T> weightClass, Class<V> resultClass, String fileName) throws IOException {
		if (results == null)
			return;
		
		Path path = FileSystems.getDefault().getPath(fileName);
		Path parent = path.getParent();
		if (parent != null)
			Files.createDirectories(parent);
		if (Files.exists(path))
			Files.delete(path);
		
		try (BufferedWriter writer = Files.newBufferedWriter(path, Charset.forName("UTF-8"), StandardOpenOption.CREATE)) {
			if (weights != null) {
				for (int i = 0; i < weights.length; i++) {
					writer.write(asString(weights[i], weightClass));
					if (i < weights.length - 1)
						writer.write(" ");
				}
				writer.newLine();
			}
			
			for (int i = 0; i < results.length; i++) {
				for (int j = 0; j < results[i].length; j++) {
					writer.write(asString(results[i][j], resultClass));
					if (j < results[i].length - 1)
						writer.write(" ");
					else if (i < results.length - 1)
						writer.newLine();
				}
			}
		}
	}
	
	private static <T> String asString(T value, Class<T> valueClass) {
		try {
			return (String) valueClass.getMethod("toString").invoke(value);
		} catch (Exception e) {
			return null;
		}
	}
}